%% Setup
% Information Structure
Info            =   struct();
Info.FixedParam =   struct('RHO_M_ext',0.81);
Info.TargetParam=   struct('RHO_M_dom',struct('lb',0,'ub',0.95),...
                           'RHO_Y_H',struct('lb',0.50,'ub',0.95),...
                           'Taylor_Pi',struct('lb',1.1,'ub',1.5),...
                           'Taylor_ir',struct('lb',0,'ub',0.95),...
                           'Cons_Elas',struct('lb',1,'ub',10),...
                           'Fin_AdjCost',struct('lb',0.01,'ub',10));
Info.ParamList  =   fieldnames(Info.TargetParam);
Info.ParamNum   =   length(Info.ParamList);

Info.StdVec     =   [1 1 1 -1 -1 60 -10]'*0.01/4;
Info.Mom_Data   =   [1;-1;-0.9;-0.3;...
                     -3/1.2;10/1.2];
Info.Weight     =   [10;10;10;10;...
                     1;1];
% Optimization 
lb              =   zeros(Info.ParamNum,1);
ub              =   zeros(Info.ParamNum,1);
for ii=1:Info.ParamNum
    vv              =   Info.ParamList{ii};
    lb(ii)          =   Info.TargetParam.(vv).lb;
    ub(ii)          =   Info.TargetParam.(vv).ub;
end
ParaVec_0       =   (lb+ub)/2;  

ObjFunction     =   @(Input)SubFun_Calibration_Eval(PP,SS,MODEL,EquJac,Info,Input);


%% Global Optimization
warning('off','all');

%--------------------------------------------------------------------------
% Particle Swarm
%--------------------------------------------------------------------------
rng default
options             =   optimoptions('particleswarm',...
                                     'Display','iter',...'SwarmSize',100.'HybridFcn',@fmincon,..
                                     'MaxTime',60*60*2,'UseParallel',true);
[ParamVec,fval,exitflag] ...
                    =   particleswarm(ObjFunction,length(lb),lb,ub,options);

[~,Mom_Model]       =   ObjFunction(ParamVec);

save('Result_1_Calibration.mat','Info','Mom_Model','ParamVec');